<?php
abstract class eCMSModuleController {
	
	/**
	 * The Reference to the Module of wich this Class is the Controller
	 * @var eCMSModule
	 */
	private $module;
	
	/**
	 * The id of the Page if submitted
	 * @var int
	 */
	private $pkPage;
	
	/**
	 * Holds the related Page Object from tblPage if a pkPage has been passed to the constructor
	 * @var PageItem
	 */
	private $page;
	
	/**
	 * The instance-id of the Module
	 * @var unknown_type
	 */
	private $fkModuleInstance;
	
	/**
	 * Holds the PageRequest Object for use later in the Controller
	 * @var PageRequest
	 */
	private $pageRequest;
	
	/* Page Content Variables */
	private $pageText, $pageTitle, $pageCreateUser, $pageCreateDate, $pageChangeUser, $pageChangeDate, $viewData;
	
	// Designmode and DesignName. Can be set by the Controller via setters, so you can costomize the design for some methods 
	private $designName, $designMode, $isPlainText;	
	
	//Toolbox Items
	private $ItemToolbox, $InstanceToolbox, $ModuleToolbox, $PageToolbox, $SiteToolbox;
	
	
	/*************************************************************
	 * System and Init Functions                                 *
	 *************************************************************/
	
	public function __construct($fkModuleInstance=null, $pkPage=null) {
		
		if(!is_null($fkModuleInstance)) { $this->setModuleInstance($fkModuleInstance); }
		if(!is_null($pkPage)) { $this->setPkPage($pkPage); }
		
		//Initialize the Toolbox-Lists
		$this->ItemToolbox = new ToolBoxList();
		$this->InstanceToolbox = new ToolBoxList();
		$this->ModuleToolbox = new ToolBoxList();
		$this->PageToolbox = new ToolBoxList();
		$this->SiteToolbox = new ToolBoxList();
				
	}
	
	public final function setModuleInstance($fkModuleInstance) {
		$this->fkModuleInstance = $fkModuleInstance;
	}
	public final function getFkModuleInstance() { return $this->fkModuleInstance; }
	
	public final function setPkPage($pkPage) {
		
		$this->pkPage = $pkPage;

		//Load PageItem
		$this->page = new PageItem($pkPage);
		
		//Get Title from Page
		$this->pageTitle = $this->page->pageTitle;
		
	}
	
	public final function getPage() {
		return $this->page;
	}
	
	public final function setModule(eCMSModule $module) {
		$this->module = $module;
	}
	
	
	
	
	/*************************************************************
	 * Site Factory Functions.                                   *
	 *************************************************************/
	
	public final function getParams() {
		
	}
	
	public final function getMethod() {
		return $this->pageRequest->getMethod();
	}
	
	public final function getIsPlainText() {
		return $this->isPlainText;
	}
	
	public final function getPkPage() {
		return $this->pkPage;
	}
	
	public final function hasToolboxItems() { 
		return (!$this->ItemToolbox->isEmpty() || !$this->InstanceToolbox->isEmpty() || !$this->PageToolbox->isEmpty() || !$this->ModuleToolbox->isEmpty() || !$this->SiteToolbox->isEmpty());
	}
	public final function getItemToolbox() { return $this->ItemToolbox; }
	public final function getInstanceToolbox() { return $this->InstanceToolbox; }
	public final function getModuleToolbox() { return $this->ModuleToolbox; }
	public final function getPageToolbox() { return $this->PageToolbox; }
	public final function getSiteToolbox() { return $this->SiteToolbox; }
	
	
	/*************************************************************
	 * Page Factory Functions. (Invoke and Bind Data to Smarty)  *
	 *************************************************************/
	
	public final function setPageRequest(PageRequest $req) {
		$this->pageRequest = $req;
	}

	public final function getModuleName() {
		return $this->module->getModuleName();	
	}

	public final function getDesignName() {	
		if(!isset($this->designName)) {
			return $this->getPage()->getDesignName(); 
		}
		else {
			return $this->designName;
		} 
	}
	
	public final function getDesignMode() {
		if(!isset($this->designMode)) {
			return $this->getPage()->getDesignMode(); 
		}
		else {
			return $this->designMode;
		} 
	}
		

	// For Compatibility, the calls are forwarded to the underlaying page
	public final function getNavTitle() { return $this->getPage()->navTitle; }
	public final function getNestedPageMode() { return $this->getPage()->getNestedPageMode(); }
	public final function getNestedPageSet() {  return $this->getPage()->getNestedPageSet(); }
	public final function getPageLayoutName() { return $this->getPage()->getPageLayoutName();	}
	public final function getParentPage() { return $this->getPage()->getParentPage(); }
	
	// Page Accessors
	public final function getText()       { return $this->pageText; }
	public final function getTitle()      { return $this->pageTitle; }
	//public final function getTitleImage() { return new ImageTexter($this->pageTitle, $this->getSetting("TitleSize", 12), $this->getSetting("TitleFont", "Arial"), $this->getSetting("TitleColor", "0x000000")); }
	public final function getCreateUser() { return $this->pageCreateUser; }
	public final function getCreateDate() { return $this->pageCreateDate; }
	public final function getChangeUser() { return $this->pageChangeUser; }
	public final function getChangeDate() { return $this->pageChangeDate; }
	
	
	public function getViewData($var=null) {
		if($var) {
			return $this->viewData[$var];
		}
		else {
			return $this->viewData;
		}
	}
	
	/*************************************************************
	 * Called on Runtome, while renedring                        *
	 *************************************************************/
	
	public final function getTitleImage() { return new ImageTexter($this->pageTitle, $this->getSetting("TitleSize", 12), $this->getSetting("TitleFont", "Arial"), $this->getSetting("TitleColor", "0x000000")); }
	
	public function getCreateUserName() { 
		return MySQLConnection::getInstance()->quickQuery("SELECT uname FROM tblSecurityUser WHERE pkSecurityUser='$this->pageCreateUser'");
	}
	
	public function getCreateUserFullName() { 
		return MySQLConnection::getInstance()->quickQuery("SELECT realname FROM tblSecurityUser WHERE pkSecurityUser='$this->pageCreateUser'");
	}
	
	public function getChangeUserName() { 
		return MySQLConnection::getInstance()->quickQuery("SELECT uname FROM tblSecurityUser WHERE pkSecurityUser='$this->pageChangeUser'");
	}
	
	public function getChangeUserFullName() { 
		return MySQLConnection::getInstance()->quickQuery("SELECT realname FROM tblSecurityUser WHERE pkSecurityUser='$this->pageChangeUser'");
	}
	
	
	
	
	/*************************************************************
	 * Page Runtime Functions (used in subclasses of the Page)   *
	 *************************************************************/
	
	protected final function setText($value) { $this->pageText = $value; }
	protected final function setTitle($value) { $this->pageTitle = $value; }
	protected final function setCreateUser($value) { $this->pageCreateUser = $value; }
	protected final function setCreateDate($value) { $this->pageCreateDate = $value; }
	protected final function setChangeUser($value) { $this->pageChangeUser = $value; }
	protected final function setChangeDate($value) { $this->pageChangeDate = $value; }
	
	protected final function setDesignName($value, $disableNestedPages=true) {
		$this->designName = $value; 
		if($disableNestedPages) {
			$this->getPage()->disableNestedPages();
		}
	}
	
	protected final function setDesignMode($value) { $this->designMode = $value; } 
	
	protected final function addViewData($varname, $data) {
		$this->viewData[$varname] = $data;
	}
	
	protected final function addToolboxItem(ToolBoxItem $i, $section="") {
		
		switch ($section) {
			
			case 'item':     $this->ItemToolbox->addItem($i); break;
			case 'instance': $this->InstanceToolbox->addItem($i); break;
			case 'module':   $this->ModuleToolbox->addItem($i); break;
			case 'page':     $this->PageToolbox->addItem($i); break;
			case 'site':     $this->SiteToolbox->addItem($i); break;
		}
		
	}
	
	public final function getUrl()				{ 
		return "?page=$this->pkPage".($this->getMethod()?"&amp;method=".$this->getMethod():"").($this->getParams()?"&amp;".$this->getParams():""); }
	
	
	//Like a getter Function
	public final function getSetting($name, $default=null) {
		$val = Runtime::getSetting($name, $this->pkModule, $this->fkModuleInstance);
		if($val=="" && isset($default)) { $val = $default; }
		return $val;
	}
	
	//Get path (relative to root) to the data of the Page. Create it, if it doas not exist
	public final function getDataDir($folder=null) {

		$cfg = Runtime::getConfiguration();
		
		//Create Base-Dir for Module-Data
		$dir = $cfg['paths']['page'] . "/content/module";
		$folder = $this->getModuleName() . "/" . $folder;
		

		$folder = str_replace("\\", "/", $folder);
		$folders = split("/", $folder);
		
		
		for($i=0;$i<sizeof($folders);$i++) {
			
			//Create Subfolder if not exists
			$dir.= "/" . $folders[$i];
			if(!file_exists($dir)) {
				$old_umask = umask(0);
				mkdir($dir,0777); // the default chmod
				umask($old_umask);
			}
			
		}
		
		return $dir; 
	}
	
	public final function getDataPath() {
		return "content/module/".$this->getModuleName();
	}
	
	/**
	 * Returns the Current PageRequest
	 * @return PageRequest
	 */
	protected final function getPageRequest() {
		return $this->pageRequest;
	}
	
	protected final function logEvent($friendly, $file, $classname, $function, $line, $vardata="") {
		
		logger::logEvent($friendly, $file, $classname, $function, $line, $vardata, $this);		
	}
	
	public final function getFkArea() {
		return $this->getPage()->getFkArea();
	}
	
	public final function getModule() {
		return $this->module;
	}
	
	protected function setJsonResponse($value) {
		$this->isPlainText = true;
		$this->setText(json_encode($value));
	}
	
	protected final function setAjaxResponse($value=null) {
		if($value) {
			$this->setText($value);
		}
		
		$this->setDesignMode("ajax");
	}	

	
	/*************************************************************
	 * Security related accessors                                *
	 *************************************************************/
	
	public final function getPageSecurityObject() {
		return $this->getPage()->getSecurityObject();
	}	
	
	public final function canInstanceUpdate() {
		return true;
	}
	
	public final function canInstanceRead() {
		return true;
	}
	
	/* Effective Methods of the Page, must be implemented */
	public abstract function index();
	public abstract function edit();
	
	
	
	
}